<?php
declare (strict_types=1);

namespace app\controller;

use app\BaseController;
use app\common\Sms;
use app\model\Config;
use app\model\User;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use thans\jwt\facade\JWTAuth;
use think\facade\Log;
use think\facade\Validate;
use think\Request;

class UserController extends BaseController
{
	protected $middleware = [
		'Login' => [
			'except' => ['login','bindWechat', 'bindMini', 'bindMobile', 'editUserInfo']
		],
	];
	
	/**
	 * 登陆
	 * @param Request $request
	 * @return void
	 * @throws GuzzleException
	 */
	function login(Request $request)
	{
		Log::record('登录');
		$mobile = $request->post('mobile', '');
		$captcha = $request->post('captcha');
		$wechat_code = $request->post('wechat_code');
		$mini_code = $request->post('mini_code');
		$mobile_code = $request->post('mobile_code');
		$login_type = $request->post('login_type/d'); //1手机号登录  2微信登录  3小程序登录
		$login_client = $request->post('login_client/d'); //1App  2微信小程序
		$client = new Client();
		$wechat_openid = '';
		$mini_openid = '';
		$unionid = '';
		$tencent = Config::getFieldByName('tencent', 'value');
		$tencent = json_decode($tencent);
		switch ($login_type) {
			case 1:
				if (!Validate::is($mobile, 'mobile')) {
					$this->writeJson(0, '手机号格式错误');
				}
				$ret = Sms::check($mobile, $captcha, 'login');
				if (!$ret) {
					$this->writeJson(0, '验证码错误');
				}
				$user = User::getByMobile($mobile);
				break;
			case 2:
				if (empty($wechat_code)) {
					$this->writeJson(0, 'wechatCode不能为空');
				}
				$response = $client->get("https://api.weixin.qq.com/sns/oauth2/access_token", [
					'query' => [
						'appid' => $tencent->wechat_appid,
						'secret' => $tencent->wechat_appsecret,
						'code' => $wechat_code,
						'grant_type' => 'authorization_code'
					]
				]);
				$response = $response->getBody()->getContents();
				$response = json_decode($response);
				Log::record('微信登录信息');
				Log::record($response);
				if (!isset($response->openid) || !isset($response->unionid)) {
					Log::record('微信登录失败');
					Log::record($request->param());
					$this->writeJson(0, '微信登录失败');
				}
				$user = User::getByUnionid($response->unionid);
				$wechat_openid = $response->openid;
				$unionid = $response->unionid;
				break;
			case 3:
				if (empty($mini_code)) {
					$this->writeJson(0, '小程序登陆失败');
				}
				
				//获取接口调用凭据
				$wechattoken = $client->get("https://api.weixin.qq.com/cgi-bin/token", [
					'query' => [
						'appid' => $tencent->mini_appid,
						'secret' => $tencent->mini_appsecret,
						'grant_type' => 'client_credential',
					]
				]);
				$wechattoken = json_decode($wechattoken->getBody()->getContents());
				if (!isset($wechattoken->access_token)){
					$this->writeJson(0, '接口调用失败');
				}
				//获取手机号
				$getMobile = $client->post("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=$wechattoken->access_token", [
					'body' => json_encode(['code' => $mobile_code])
				]);
				$getMobile = json_decode($getMobile->getBody()->getContents());
				if ($getMobile->errcode!=0){
					$this->writeJson(0,$getMobile->errmsg);
				}
				$mobile = $getMobile->phone_info->purePhoneNumber;
				$login = $client->get("https://api.weixin.qq.com/sns/jscode2session", [
					'query' => [
						'appid' => $tencent->mini_appid,
						'secret' => $tencent->mini_appsecret,
						'js_code' => $mini_code,
						'grant_type' => 'authorization_code'
					]
				]);
				$login = json_decode($login->getBody()->getContents());
				if (!isset($login->openid) || !isset($login->unionid)) {
					$this->writeJson(0, '小程序登陆失败');
				}
				
			
				$user = User::getByUnionid($login->unionid);
				$mini_openid = $login->openid;
				$unionid = $login->unionid;
				break;
			default:
				$this->writeJson(0, '登录方式错误');
		}
		$time = time();
		$ip = $request->ip();
		if ($user) {
			if ($login_type==2){
				if (!$user->wechat_openid){
					$user->wechat_openid = $wechat_openid;
				}
			}
			if ($login_type==3){
				if (!$user->mini_openid){
					$user->mini_openid = $mini_openid;
				}
				if (!$user->mobile){
					$user->mobile = $mobile;
				}
			}
			$user->prevtime = $user->logintime;
			$user->logintime = $time;
			$user->loginip = $ip;
			$user->save();
		} else {
			$user = User::create([
				'logintime' => $time,
				'loginip' => $ip,
				'jointime' => $time,
				'joinip' => $ip,
				'nickname' => '用户' . rand(1000000, 9999999),
				'avatar' => '/assets/img/avatar.png',
				'mobile' => $mobile,
				'wechat_openid' => $wechat_openid,
				'mini_openid' => $mini_openid,
				'unionid' => $unionid,
			]);
		}

		switch ($login_client) {
			case 1:
				if (empty($user->wechat_openid)) {
					$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 102]);
					$this->writeJson(102, '请先绑定微信', '', 'json', ['Authorization' => 'Bearer ' . $token]);
				}
				break;
			case 2:
				if (empty($user->mini_openid)) {
					$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 104]);
					$this->writeJson(104, '请先绑定小程序', '', 'json', ['Authorization' => 'Bearer ' . $token]);
				}
				break;
			default:
				$this->writeJson(0, '登陆终端异常');
		}
		
		Log::record($user);
		if (empty($user->mobile)) {
			$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 103]);
			$this->writeJson(103, '请先绑定手机号', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		if (!$user->nickname || !$user->avatar || !$user->birthday || !$user->height || !$user->city || !$user->email) {
			$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 105]);
			$this->writeJson(105, '请先完善资料', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		if ($user->happy_out->isEmpty()){
			$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 106]);
			$this->writeJson(106, '请先填写幸福感问卷调查', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		if ($user->life_out->isEmpty()){
			$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 107]);
			$this->writeJson(107, '请先填写生活方式问卷调查', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		
		$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 1]);
		$this->writeJson(1, '登录成功', '', 'json', ['Authorization' => 'Bearer ' . $token]);
	}
	
	/**
	 * 绑定微信
	 * @param Request $request
	 * @return void
	 * @throws GuzzleException
	 */
	function bindWechat(Request $request)
	{
		if (empty($this->user_id)){
			$this->writeJson(401, '请先登录');
		}
		$wechat_code = $request->post('wechat_code');
		$tencent = Config::getFieldByName('tencent', 'value');
		$tencent = json_decode($tencent);
		$client = new Client();
		$response = $client->get("https://api.weixin.qq.com/sns/oauth2/access_token", [
			'query' => [
				'appid' => $tencent->wechat_appid,
				'secret' => $tencent->wechat_appsecret,
				'code' => $wechat_code,
				'grant_type' => 'authorization_code'
			]
		]);
		$response = $response->getBody()->getContents();
		$response = json_decode($response);
		if (!isset($response->openid) || !isset($response->unionid)) {
			$this->writeJson(0, '绑定微信失败');
		}
		
		if (User::getByWechatOpenid($response->openid)) {
			$this->writeJson(0, '该微信已被绑定');
		}
		
		$user = User::findOrFail($this->user_id);
		$user->wechat_openid = $response->openid;
		$user->unionid = $response->unionid;
		$user->save();
		JWTAuth::refresh();
		if (!$user->nickname || !$user->avatar || !$user->birthday || !$user->height || !$user->city || !$user->email) {
			$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 105]);
			$this->writeJson(105, '请先完善资料', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 1]);
		$this->writeJson(1, '登录成功', '', 'json', ['Authorization' => 'Bearer ' . $token]);
	}
	
	/**
	 * 绑定小程序
	 * @param Request $request
	 * @return void
	 * @throws GuzzleException
	 */
	function bindMini(Request $request)
	{
		Log::record('绑定小程序');
		if (empty($this->user_id)){
			$this->writeJson(401, '请先登录');
		}
		$mini_code = $request->post('mini_code');
		$client = new Client();
		$tencent = Config::getFieldByName('tencent', 'value');
		$tencent = json_decode($tencent);
		$response = $client->get("https://api.weixin.qq.com/sns/jscode2session", [
			'query' => [
				'appid' => $tencent->mini_appid,
				'secret' => $tencent->mini_appsecret,
				'js_code' => $mini_code,
				'grant_type' => 'authorization_code'
			]
		]);
		$response = $response->getBody()->getContents();
		$response = json_decode($response);
		
		if (!isset($response->openid) || !isset($response->unionid)) {
			$this->writeJson(0, '绑定小程序失败');
		}
		
		if (User::getByMiniOpenid($response->openid)) {
			$this->writeJson(0, '该小程序已被绑定');
		}
		
		$user = User::findOrFail($this->user_id);
		$user->mini_openid = $response->openid;
		$user->unionid = $response->unionid;
		$user->save();
		JWTAuth::refresh();
		if (!$user->nickname || !$user->avatar || !$user->birthday || !$user->height || !$user->city || !$user->email) {
			$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 105]);
			$this->writeJson(105, '请先完善资料', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 1]);
		$this->writeJson(1, '登录成功', '', 'json', ['Authorization' => 'Bearer ' . $token]);
	}
	
	
	/**
	 * 绑定手机号
	 * @param Request $request
	 * @return void
	 */
	function bindMobile(Request $request)
	{
		if (empty($this->user_id)){
			$this->writeJson(401, '请先登录');
		}
		$mobile = $request->post('mobile');
		$captcha = $request->post('captcha');
		if (!Validate::is($mobile, 'mobile')) {
			$this->writeJson(0, '手机号格式错误');
		}
		$ret = Sms::check($mobile, $captcha, 'changemobile');
		if (!$ret) {
			$this->writeJson(0, '验证码错误');
		}
		if (User::getByMobile($mobile)) {
			$this->writeJson(0, '手机号已存在');
		}
		$user = User::findOrFail($this->user_id);
		Log::record('绑定手机号');
		Log::record($user);
		$user->mobile = $mobile;
		$user->save();
		JWTAuth::refresh();
		if (!$user->nickname || !$user->avatar || !$user->birthday || !$user->height || !$user->city || !$user->email) {
			$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 105]);
			$this->writeJson(105, '请先完善资料', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 1]);
		$this->writeJson(1, '登录成功', '', 'json', ['Authorization' => 'Bearer ' . $token]);
	}
	
	
	/**
	 * 验证手机号
	 * @param Request $request
	 * @return void
	 */
	function validateMobile(Request $request)
	{
		$mobile = $request->post('mobile');
		$captcha = $request->post('captcha');
		if (!Validate::is($mobile, 'mobile')) {
			$this->writeJson(0, '手机号格式错误');
		}
		$ret = Sms::check($mobile, $captcha, 'validatemobile');
		if (!$ret) {
			$this->writeJson(0, '验证码错误');
		}
		$this->writeJson(1,'验证成功');
	}
	
	/**
	 * 获取用户信息
	 * @return void
	 */
	function getUserInfo()
	{
		$row = User::findOrFail($this->user_id);
		$this->writeJson($row);
	}
	
	/**
	 * 编辑用户信息
	 * @param Request $request
	 * @return void
	 */
	function editUserInfo(Request $request)
	{
		if (empty($this->user_id)){
			$this->writeJson(401, '请先登录');
		}
		$params = array_filter($request->post());
		$params['id'] = $this->user_id;
		$user = User::findOrFail($this->user_id);
		try {
			validate(\app\validate\User::class)->only(array_keys($params))->check($params);
		} catch (\Exception $e) {
			$this->writeJson(0,$e->getMessage());
		}
		
		$user->data($params);
		$user->save();
		JWTAuth::refresh();
		if ($user->happy_out->isEmpty()){
			$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 106]);
			$this->writeJson(106, '请先填写幸福感问卷调查', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		if ($user->life_out->isEmpty()){
			$token = JWTAuth::builder(['user_id' => $user->id, 'user_status' => 107]);
			$this->writeJson(107, '请先填写生活方式问卷调查', '', 'json', ['Authorization' => 'Bearer ' . $token]);
		}
		
		$token = JWTAuth::builder(['user_id' => $this->user_id, 'user_status' => 1]);
		$this->writeJson(1, '登录成功', '', 'json', ['Authorization' => 'Bearer ' . $token]);
	}
	
	/**
	 * 注销
	 * @return void
	 */
	function userOff()
	{
		$user = User::findOrFail($this->user_id);
		$user->delete();
		JWTAuth::refresh();
		$this->writeJson();
	}

	
}
